<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
     0.区别
        let声明的范围是块作用域
        var声明的范围是函数作用域
 */

    // 0.1 举例var
    if (true) {
        var name = "Matt"
    }
    console.log('第12行name', name) // Matt   ,但是注意,当为false的时候,name的值为undefined;

    // 0.2 举例let
    if (true) {
        let age = 18;
    }
    // console.log('第17行age',age)   // 报错

    // 0.3 声明多次
    var sex = 10;
    var sex = 11;
    let hobby;
    // let hobby;  // 这里报错,声明了多次
    console.log('第24行sex', sex)  // var 声明的多个,取后面的一个

    // 1. 之前提到的 var可以提升,let不能提升

    // 2.全局声明
    var name2 = 'Matt'
    console.log('第30行name2', window.name2, window.name2 === name2) // Matt true

    let age2 = 26;
    console.log('第44行age2', window.age2)  // undefined

    // 3.条件声明,看下面的一个script
    var name3 = 'Nicholas'
    let age3 = 26;

    // 4.for循环中的let声明
    // 4.1 使用var的时候,for循环中的变量会渗透到循环体外部
    for (var i4 = 0; i4 < 5; ++i4) {

    }
    console.log('第55行i4', i4)    // 5

    // 4.2 使用let之后,就不会出现这个问题了
    for (let j = 0; j < 5; j++) {

    }
    // console.log('第61行j',j)  // 报错,未定义

    // 4.3 加入异步
    for (var step1 = 0; step1 < 5; step1++){
        setTimeout(() =>console.log('第65行step1',step1))  // 全都是5
    }
    for(let step2 = 0;step2 <5;step2++){ // 其原理我也不是很清楚
        // 官方解释为:使用let声明迭代变量时,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量,每个setTimeout引用的都是不同的变量实例
        setTimeout(() =>console.log('第69行step2',step2))  // 0,1,2,3,4
    }
</script>
<script>
    var name3 = 'Matt'          // 正常
    // let age3 = 36;              // 报错,已经声明过了
</script>
</body>
</html>

